Flutter 入门-本地访问-MethodChannel

Dart4Flutter - 01 – 变量、类型和函数

Dart4Flutter – 02 –控制流 和异常

Dart4Flutter – 03 – 类和泛型

Dart4Flutter – 04 – 异步和库

Dart4Flutter - 拾遗01 - flutter-dart环境搭建

Dart4Flutter - 不可变性

Flutter入门 - 状态管理

Flutter 入门实例1

Flutter 入门 - Container 属性详解

Flutter 入门-本地访问-MethodChannel

Flutter 实例 - 加载更多的ListView

Flutter 实例 - 从本地到Flutter通信 - Event Channels

Flutter 作为一种跨平台的解决方案,有访问本地资源的能力。主要是通过Channel完成,你可以称之为隧道。主要是MethodChannel和MessageChannel两种,第一种是调用方法,第二种是传递信息。首先通信的双方是Flutter和本地操作系统或者应用,而且方法的调用和消息的方法可以从任何一方发起,类似RPC(远程过程调用)。

重点内容:

  • 主要是Flutter是一个比较独立的环境,要想访问本地的资源,Flutter提供了Channel机制,类似Cilent-Server模式或者RPC
  • 通过Channel的名称打通Channel,隧道。
  • Flutter和本地是对称的,请求可以从任何一发发起,本教程主要是从Flutter给本地发送请求。

Flutter部分

如果你对Flutter的界面编写部分不熟悉,可以参考官方的文档;

下面是UI部分的代码

import 'package:flutter/material.dart';


void main() {
  runApp(new MaterialApp(
    home: new Scaffold(
      body: new PlatformTestBody(),
    ),
  ));
}

class PlatformTestBody extends StatefulWidget {
  @override
  PlatformTestBodyState createState() {
    return new PlatformTestBodyState();
  }
}

class PlatformTestBodyState extends State<PlatformTestBody> {

  String nativeMessage =''; 
  @override
  Widget build(BuildContext context) {
    return new Container(
      color: Colors.pinkAccent,
      child: new Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: <Widget>[
          new Padding(
            padding: const EdgeInsets.only(left: 18.0, top: 200.0),
            child: new Text(
              'Tap the button to change your life!',
              style: new TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.w500,
                  fontSize: 23.0),
            ),
          ),
          new Padding(
            padding: const EdgeInsets.only(left: 8.0, right: 8.0, top: 102.0),
            child: new RaisedButton(
              child: new Text('Click Me'),
              onPressed: () => print(''),
            ),
          ),
          new Padding(
            padding: const EdgeInsets.only(left: 8.0, right: 8.0, top: 102.0),
            child: new Text(
              nativeMessage,
              style: new TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.w500,
                  fontSize: 23.0),
            ),
          )
        ],
      ),
    );
  }
}
复制代码

现在我们介绍关于本地资源访问的问题,首先我们要引入service包和async包。

// Add these lines to the top of the file
import 'package:flutter/services.dart';
import 'dart:async';
复制代码

有了service包,我们就可以配置Flutter,发送请求到本地。声明一个static const变量platformMethodChannel ,赋值MethodChannel类型的对象。

class PlatformTestBodyState extends State<PlatformTestBody> {
  //Add this line 
  static const platformMethodChannel = const MethodChannel('com.test/test');

  String nativeMessage ='';  
  @override
  Widget build(BuildContext context) {
      ...
复制代码

注意,我们给MethodChannel一个名字com.test/test,这个名字和本地那边的要一样。

我们创建了MethodChannel,我们准备一个用来发送请求的函数。我们创建一个叫doNativeSuff的异步函数

Future<Null> doNativeSuff() async {
 
  }
复制代码

代替RaisedButton中的onPressed函数 print('')doNativeSuff()

child: new RaisedButton(
    child: new Text('Click Me'),
    onPressed: () => print(''),
),
复制代码
child: new RaisedButton(
    child: new Text('Click Me'),
    onPressed: () => doNativeSuff(),
),
复制代码

下面解释整个doNativeSuff 方法

Future<Null> doNativeSuff() async {
    String _message; // 1
    try {
      final String result =
          await platformMethodChannel.invokeMethod('changeLife');// 2
      _message = result;
      print(result);
    } on PlatformException catch (e) {
      _message = "Sadly I can not change your life: ${e.message}.";
    }
    setState(() {
        nativeMessage = _message; // 3
    });
  }
复制代码
  1. 声明一个String变量_message,用于存需要显示在界面上的信息,可能来自本地,也可能来自Flutter
  2. 发送请求,await platformMethodChannel.invokeMethod('changeLife') 是调用本地的changeLife 方法,并且这个方法是异步的,await表示阻塞执行。
  3. nativeMessage = _message; 表示通知Flutter状态改变,刷新界面。

本地部分

本教程只关注Android方面的代码。在Android studio 中打开MainActivity.java,在文件的最顶上添加一下代码,是Flutter插件的相关依赖

import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
复制代码

声明CHANNEL 变量,和Flutter中MethodChannel的名字一样com.test/test,建议直接从Flutter那边复制粘贴。

public class MainActivity extends FlutterActivity {
  private static final String CHANNEL = "com.test/test"; 
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    ...
复制代码

使用上面的CHANNELFlutterView 创建一个MethodChannel

public class MainActivity extends FlutterActivity {
  private static final String CHANNEL = "com.test/test";
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    GeneratedPluginRegistrant.registerWith(this);
    new MethodChannel(getFlutterView(), CHANNEL)// 重点
复制代码

在MethodChannel的中调用.setMethodCallHandler() 方法,需要一个MethodCallHandler 对象,是一个匿名内部类,有一个方法onMethodCall,在Flutter发送请求事,onMethodCall方法会执行。

public class MainActivity extends FlutterActivity {
  private static final String CHANNEL = "com.test/test";
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    GeneratedPluginRegistrant.registerWith(this);
    new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
      new MethodCallHandler() {
        @Override
        public void onMethodCall(MethodCall methodCall, Result result) {
        }
      }
    );
  }

}
复制代码

onMethodCall方法中有两个参数 MethodCall 和 result,MethodCall 中有关当前请求的信息,例如调用方法的名字changeLife;Result用于发送信息给Flutter。

在onMethodCall中判断当前请求是否为changeLife,如果是通过resultsuccess 返回信息:Life Changed .

public void onMethodCall(MethodCall methodCall, Result result) {
  if (methodCall.method.equals("changeLife")){
    String message ="Life Changed";
    result.success(message);
  }
  ...
复制代码

这样Flutter就可以访问,本地的方法了。

通常应用于访问本地资源,例如访问相机,本地存储,图片的选择

本教程主要了解的是MethodChannel,还有MessageChannel没有解析,下次再说。

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flutter中的TextField是一个常用的输入控件,它允许用户在应用程序中输入文本。 TextField通常用于表单中,可以接收用户输入的文本,比如用户名、密码、电子邮件地址等。 以下是一个基本的TextField示例: ```dart TextField( decoration: InputDecoration( hintText: '请输入文本', ), ); ``` 在上面的示例中,我们使用了decoration属性来设置TextField的外观,其中hintText属性用于设置提示文本。 TextField还有许多其他的属性可以设置,比如maxLength(允许输入的最大长度)、keyboardType(键盘类型)、obscureText(是否隐藏输入内容)等等。 下面是一个更完整的TextField示例: ```dart class MyTextField extends StatefulWidget { @override _MyTextFieldState createState() => _MyTextFieldState(); } class _MyTextFieldState extends State<MyTextField> { final TextEditingController _controller = TextEditingController(); @override Widget build(BuildContext context) { return TextField( controller: _controller, maxLength: 10, keyboardType: TextInputType.text, obscureText: true, decoration: InputDecoration( hintText: '请输入文本', labelText: '文本框', prefixIcon: Icon(Icons.text_fields), suffixIcon: IconButton( icon: Icon(Icons.clear), onPressed: () { setState(() { _controller.clear(); }); }, ), border: OutlineInputBorder(), ), onChanged: (value) { print('输入的文本为:$value'); }, ); } } ``` 在上面的示例中,我们使用了TextEditingController来控制TextField的文本内容,maxLength属性限制了用户输入的最大长度为10,keyboardType属性指定了键盘类型为文本类型,obscureText属性设置为true表示隐藏输入内容。 此外,我们还设置了decoration属性来自定义TextField的外观,包括了输入提示文本、标签文本、前缀图标、后缀图标和边框样式等。 最后,我们通过onChanged回调函数来监听用户输入的文本,并打印出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值